package com.javatip.project.deep_learning.predict.service;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantLock;

import com.javatip.common.utils.RunPythonScript;
import com.javatip.common.utils.Utils;
import com.javatip.common.utils.file.FileUtils;
import com.javatip.project.deep_learning.app01Dataset.service.App01DatasetServiceImpl;
import com.javatip.project.deep_learning.app01Dataset.service.IApp01DatasetService;
import com.javatip.project.deep_learning.model.domain.Model;
import com.javatip.project.deep_learning.model.service.IModelService;
import com.javatip.project.deep_learning.predict.controller.PredictController;
import com.javatip.project.deep_learning.trainMission.domain.TrainMission;
import com.javatip.project.deep_learning.trainMission.service.ITrainMissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.javatip.project.deep_learning.predict.mapper.PredictMapper;
import com.javatip.project.deep_learning.predict.domain.Predict;
import com.javatip.project.deep_learning.predict.service.IPredictService;
import com.javatip.common.utils.text.Convert;

import static com.javatip.common.utils.security.ShiroUtils.getSysUser;

/**
 * 识别 服务层实现
 *
 * @author 袁伟
 * @date 2024-07-24
 */
@Service
public class PredictServiceImpl implements IPredictService {
    @Autowired
    private PredictMapper predictMapper;

    @Autowired
    private ITrainMissionService trainMissionService;

    @Autowired
    private IModelService modelService;

    @Autowired
    private IApp01DatasetService app01DatasetService;

    @Autowired
    private App01DatasetServiceImpl app01DatasetServiceImpl;

    /**
     * 查询识别信息
     *
     * @param id 识别ID
     * @return 识别信息
     */
    @Override
    public Predict selectPredictById(Integer id) {
        return predictMapper.selectPredictById(id);
    }

    /**
     * 查询识别列表
     *
     * @param predict 识别信息
     * @return 识别集合
     */
    @Override
    public List<Predict> selectPredictList(Predict predict) {
        return predictMapper.selectPredictList(predict);
    }

    /**
     * 新增识别
     *
     * @param predict 识别信息
     * @return 结果
     */
    @Override
    public int insertPredict(Predict predict) {
        predict.setUserId(getSysUser().getUserId().intValue());
        return predictMapper.insertPredict(predict);
    }

    /**
     * 修改识别
     *
     * @param predict 识别信息
     * @return 结果
     */
    @Override
    public int updatePredict(Predict predict) {
        return predictMapper.updatePredict(predict);
    }


    // 保存每个识别任务的进程信息
    private final ConcurrentHashMap<Integer, Process> processMap = new ConcurrentHashMap<>();
    private final ExecutorService executorService = Executors.newCachedThreadPool();
    // 全局标志，表示是否正在停止识别任务
    private volatile boolean stopFlag = false;
    // 全局锁，确保任务的同步执行
    private final ReentrantLock lock = new ReentrantLock();

    /**
     * 删除识别对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deletePredictByIds(String ids) {
        Predict predictMission = predictMapper.selectPredictById(Integer.parseInt(ids));
//		获取当前路径
        String currentPath = System.getProperty("user.dir");
//		构造删除文件路径，为/predictResult/trainMissionId/datasetId/下的文件
        String deletePath = currentPath + "/src/main/resources/predictResult/" + predictMission.getUserId() + '/' + String.valueOf(predictMission.getTrainMissionId()) + "/" + predictMission.getDatasetId();
        //删除文件
        System.out.println("删除路径：" + deletePath);
        FileUtils.deleteFolderFile(deletePath);
        //删除数据库记录
//		成功返回1，失败返回0
//		int i = predictMapper.deletePredictById(id);
//		System.out.println("i"+i);
        return predictMapper.deletePredictByIds(Convert.toStrArray(ids));
    }

    /**
     * @param id
     * @return
     */
    @Override
    public int predict(Integer id) {
        if (stopFlag) {
            System.out.println("全局停止标志已设置，不启动新的训练任务");
            return 1;
        }
        Predict predictMission = predictMapper.selectPredictById(id);
        if (predictMission == null) {
            System.out.println("未找到对应的识别任务");
            return 1;
        }

//        System.out.println("predictMission: " + predictMission);
        int trainMissionId = predictMission.getTrainMissionId();
        String modelName = trainMissionService.selectTrainMissionById(trainMissionId).getModel();
        Integer modelUserId = modelService.selectModelById(trainMissionService.selectTrainMissionById(trainMissionId).getModelId()).getUserId();
        String datasetTrainLocation = app01DatasetService.selectApp01DatasetById(trainMissionService.selectTrainMissionById(trainMissionId).getDatasetTrainId()).getLocation();
        String datasetTrainName = app01DatasetService.selectApp01DatasetById(trainMissionService.selectTrainMissionById(trainMissionId).getDatasetTrainId()).getName();
        String datasetValLocation = app01DatasetService.selectApp01DatasetById(trainMissionService.selectTrainMissionById(trainMissionId).getDatasetValId()).getLocation();
        String datasetValName = app01DatasetService.selectApp01DatasetById(trainMissionService.selectTrainMissionById(trainMissionId).getDatasetValId()).getName();
        int batchSize = trainMissionService.selectTrainMissionById(trainMissionId).getBatchSize();
        int minEpoch = trainMissionService.selectTrainMissionById(trainMissionId).getMinEpoch();
        int maxEpoch = trainMissionService.selectTrainMissionById(trainMissionId).getMaxEpoch();
        Integer earlyStop = trainMissionService.selectTrainMissionById(trainMissionId).getEarlyStop();
        Float opLr = trainMissionService.selectTrainMissionById(trainMissionId).getOpLr();
        Integer modelId = trainMissionService.selectTrainMissionById(trainMissionId).getModelId();
        String location = app01DatasetService.selectApp01DatasetById(predictMission.getDatasetId()).getLocation();
        int imageSize=app01DatasetService.selectApp01DatasetById(predictMission.getDatasetId()).getHeight();
        int datasetId = predictMission.getDatasetId();

//		status设置为识别中
        predictMission.setStatus("识别中");
        predictMission.setBeginTime(new java.util.Date());
        predictMission.setRunning(true);
        predictMapper.updatePredict(predictMission);

//        System.out.println("modelName: " + modelName);
//        System.out.println("modelUserId: " + modelUserId);
//        System.out.println("datasetTrainLocation: " + datasetTrainLocation);
//        System.out.println("datasetTrainName: " + datasetTrainName);
//        System.out.println("datasetValLocation: " + datasetValLocation);
//        System.out.println("datasetValName: " + datasetValName);
//        System.out.println("batchSize: " + batchSize);
//        System.out.println("minEpoch: " + minEpoch);
//        System.out.println("maxEpoch: " + maxEpoch);
//        System.out.println("earlyStop: " + earlyStop);
//        System.out.println("opLr: " + opLr);
//        System.out.println("modelId: " + modelId);
//        System.out.println("location: " + location);
//        System.out.println("datasetId: " + datasetId);

        //获取当前路径
        String currentPath = System.getProperty("user.dir").toString().replace("\\","/");
        String parentParentPath = Utils.getParentPath(currentPath, 0);
//		parentParentPath: /home/jolly/develop/project/java
        currentPath = parentParentPath + "/src/main/resources/CorsicanFire/segmentation";

        int inputChan=modelService.selectModelById(trainMissionService.selectTrainMissionById(trainMissionId).getModelId()).getInputChannel();
        int outChan=modelService.selectModelById(trainMissionService.selectTrainMissionById(trainMissionId).getModelId()).getOutputChannel();

        Process process = null;

//        System.out.println("predictMission.getUserId()" + String.valueOf(predictMission.getUserId()));
        try {
            // 使用 ProcessBuilder 启动进程
            ProcessBuilder pb = new ProcessBuilder("python", currentPath + "/predict_java.py",
                    String.valueOf(trainMissionId),
                    modelName,
                    String.valueOf(modelUserId),
                    datasetTrainLocation,
                    datasetTrainName,
                    datasetValLocation,
                    datasetValName,
                    String.valueOf(batchSize),
                    String.valueOf(minEpoch),
                    String.valueOf(maxEpoch),
                    String.valueOf(earlyStop),
                    String.valueOf(imageSize),
                    String.valueOf(modelId),
                    location,
                    String.valueOf(datasetId),
                    String.valueOf(predictMission.getUserId()),
                    String.valueOf(inputChan),
                    String.valueOf(outChan)
            );
            pb.redirectErrorStream(true); // 合并标准输出和标准错误
            process = pb.start();

            // 读取 Python 脚本的输出
            Process finalProcess = process; // 为了在内部类中使用
            new Thread(() -> {
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(finalProcess.getInputStream()))) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        System.out.println(line);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
            System.out.println("Python 脚本已启动");
            // 保存进程信息
            processMap.put(id, process);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (process != null) {
            // 等待 Python 脚本执行完毕
            try {
                int i = process.waitFor();
                System.out.println("Python 脚本已执行完毕");
                //		运行对比图
                if (i == 0) {
                    try {
                        // 使用 ProcessBuilder 启动进程
                        System.out.println("开始执行结果对比脚本");
                        ProcessBuilder pb = new ProcessBuilder("python", currentPath + "/compare_saveImage.py", location, currentPath
                                + "/../../predictResult/" + predictMission.getUserId() +
                                '/' + String.valueOf(predictMission.getTrainMissionId()) + "/" + predictMission.getDatasetId() + "/predictResult");
                        pb.redirectErrorStream(true); // 合并标准输出和标准错误
                        process = pb.start();
                        System.out.println("Python 识别对比脚本已启动");

                        // 读取 Python 脚本的输出
                        Process finalProcess = process; // 为了在内部类中使用
                        new Thread(() -> {
                            try (BufferedReader reader = new BufferedReader(new InputStreamReader(finalProcess.getInputStream()))) {
                                String line;
                                while ((line = reader.readLine()) != null) {
                                    System.out.println(line);
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }).start();
                        processMap.put(id, process);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }finally {

                    }
                    // 等待 Python 脚本执行完毕
                    try {
                        process.waitFor();
                        System.out.println("Python sssssssssssssssssssssssss识别结果对比脚本已执行完毕");
                        //                        如果loaction下有tif文件夹，则执行tifToGeojson.py脚本
//                        System.out.println("准备执行tifToGeojson脚本");
                        boolean exist = FileUtils.isExist(location + "/tif");
//                        System.out.println("existence of tif folder: "+exist);
                        /*
                         检测推理任务的数据集目录下是否有tif文件夹，如果有，就把数据集的地理信息赋给推理后的图片
                         */
                        int trainMissionid = predictMission.getTrainMissionId();
                        int datasetid = predictMission.getDatasetId();
                        // 推理文件夹路径
//                        String inferencePath = currentPath + "/src/main/resources/predictResult/" + predictMission.getUserId() + '/' + trainMissionid + "/" + datasetid;

                        // 获取文件路径
                        String currentPath1 = System.getProperty("user.dir").toString().replace("\\","/");
                        String filePath = currentPath1 + "/src/main/resources/predictResult/" + predictMission.getUserId() + '/' + trainMissionid + "/" + datasetid + "/predictResult/";
                        Integer selectedDatasetId = predictMission.getDatasetId();
                        Integer datasetUserId = app01DatasetServiceImpl.selectApp01DatasetById(selectedDatasetId).getUserId();// 获取数据集归属者id
                        String datasetPath = currentPath1 + "/src/main/resources/datasets/" + datasetUserId + "/" +
                                app01DatasetServiceImpl.selectApp01DatasetById(selectedDatasetId).getName() + "/";
                        // 检测datasetPath下是否有名为tif的文件夹
                        // 构建tif文件夹的路径
                        String tifFolderPath = datasetPath + "tif";
                        // 检查tif文件夹是否存在
                        File tifFolder = new File(tifFolderPath);
                        System.out.println("tif文件夹路径：" + tifFolderPath);
                        boolean tifFolderExist = tifFolder.exists() && tifFolder.isDirectory();
                        // 如果tif文件夹存在，执行Python脚本
                        if (tifFolderExist) {
                            predictMission.setStatus("转化格式");
                            predictMapper.updatePredict(predictMission);
                            System.out.println("The 'tif' folder exists. Proceeding with processing...");

                            // 输入、输出路径
                            String pngInputPath = filePath; // 输入PNG文件路径
                            String tifInputPath = datasetPath + "tif/";
                            String shapefileOutputPath = filePath + "../shp/"; // 输出Shapefile路径
                            // 创建shp文件夹
                            File shpFolder = new File(shapefileOutputPath);
                            System.out.println("shp 文件夹路径：" + shapefileOutputPath);
                            if (!shpFolder.exists()) {
                                shpFolder.mkdirs();
                            }

                            // 构建Python脚本路径
                            String pythonScriptPath = currentPath1 + "/src/main/resources/CorsicanFire/segmentation/批量轮廓提取V2.py";

                //            System.out.println("pythonScriptPath: "+pythonScriptPath);
                //            System.out.println("pngInputPath: "+pngInputPath);
                //            System.out.println("tifOutputPath: "+tifInputPath);

                            // 调用Python脚本执行处理任务
                            RunPythonScript.runPythonScriptWithGeoArgs(pythonScriptPath, pngInputPath, tifInputPath, shapefileOutputPath);
                        } else {
                            System.out.println("The 'tif' folder does not exist in the dataset path.");
                        }
//                        if (FileUtils.isExist(location + "/tif")){
//                            System.out.println("predict_java.py 执行完毕" );
//// 创建jsonOutput文件夹
//                            String jsonOutputPath = currentPath + "/../../predictResult/" + predictMission.getUserId() + '/'
//                                    + (predictMission.getTrainMissionId()) + "/" + predictMission.getDatasetId() + "/jsonOutput/";
//                            FileUtils.createFolder(jsonOutputPath);
//                            ProcessBuilder pb = new ProcessBuilder(
//                                    "python",
//                                    currentPath + "/tifToGeojson.py",  // 脚本路径
//                                    "--image_folder", location + "/tif/",  // 图像文件夹路径
//                                    "--label_folder", currentPath + "/../../predictResult/" + predictMission.getUserId() + '/'
//                                    + (predictMission.getTrainMissionId()) + "/" + predictMission.getDatasetId() + "/predictResult/",  // 标签文件夹路径
//                                    "--output_folder", currentPath + "/../../predictResult/" + predictMission.getUserId() + '/'
//                                    + (predictMission.getTrainMissionId()) + "/" + predictMission.getDatasetId() + "/jsonOutput/"  // 输出文件夹路径
//                            );
//                            System.out.println("执行tifToGeojson脚本命令: " + pb.command());
//                            pb.redirectErrorStream(true); // 合并标准输出和标准错误
//
//                            // 启动tifToGeojson脚本
//                            new Thread(() -> {
//                                try {
//                                    Process tifProcess = pb.start();
//                                    System.out.println("Python tifToGeojson脚本已启动");
//
//                                    // 读取 Python 脚本的输出
//                                    try (BufferedReader reader = new BufferedReader(new InputStreamReader(tifProcess.getInputStream()))) {
//                                        String line;
//                                        while ((line = reader.readLine()) != null) {
//                                            System.out.println(line);  // 打印输出
//                                        }
//                                    }
//                                    tifProcess.waitFor();
//                                } catch (IOException | InterruptedException e) {
//                                    e.printStackTrace();
//                                }
//                            }).start();
//                        }
                        predictMission.setStatus("已完成");
                        predictMission.setRunning(false);
                        predictMission.setEndTime(new java.util.Date());
                        predictMapper.updatePredict(predictMission);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                processMap.remove(id);
                if (!stopFlag) {

                } else {
                    System.out.println("全局停止标志已设置，停止识别任务");
                }
            }
        } else {
            System.out.println("Python 脚本启动失败");
            predictMission.setStatus("识别异常");
            predictMapper.updatePredict(predictMission);
            predictMission.setRunning(false);
            return 1;
        }
        return 0;

    }

    public boolean stopSingePredict(Integer id) {
        lock.lock();
        try {
            if (stopFlag) {
                System.out.println("全局停止标志已设置，不启动新的识别任务");
                return false;
            }
            System.out.println("processMap: " + processMap.toString());
            Process process = processMap.get(id);
            if (process != null) {
                System.out.println("停止识别任务：" + id);
                process.destroy();

                try {
                    stopFlag = true;
                    process.waitFor();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                processMap.remove(id);
                Predict predictMission = predictMapper.selectPredictById(id);
                if (predictMission != null) {
                    predictMission.setStatus("未识别");
                    predictMission.setRunning(false);
                    predictMapper.updatePredict(predictMission);
                }
                return true;
            }
            System.out.println("任务未找到或已停止");
            return false; // 如果进程不存在，返回 false
        } finally {
            stopFlag = false;
            lock.unlock();
        }
    }

    @Override
    public String getInferenceStatus(Integer id) {
        System.out.println("getInferenceStatus id:"+id);
        return predictMapper.selectPredictById(id).getStatus();
    }

    @Override
    public int deletePredictById(Integer id) {
        Predict predictMission = predictMapper.selectPredictById(id);
//		获取当前路径
        String currentPath = System.getProperty("user.dir");
//		构造删除文件路径，为/predictResult/trainMissionId/datasetId/下的文件
        String deletePath = currentPath + "/src/main/resources/predictResult/" + predictMission.getUserId() + '/' + String.valueOf(predictMission.getTrainMissionId()) + "/" + predictMission.getDatasetId();
        //删除文件
        System.out.println("删除路径：" + deletePath);
        FileUtils.deleteFolderFile(deletePath);
        //删除数据库记录
//		成功返回1，失败返回0
//		int i = predictMapper.deletePredictById(id);
//		System.out.println("i"+i);
        return 1;
    }


    @Override
    public int doPredict() {
//        lock.lock(); // 加锁，确保任务执行的互斥性
        try {
            if (stopFlag) {
                // 如果正在停止任务，直接返回
                return 1;
            }

            int result = 0; // Python 脚本的运行结果，0 为正常退出
            int status = predictMapper.isTraining(); // 查询是否有正在训练的任务); // 检查当前的训练状态
//            System.out.println("status：" + status);
            if (processMap.isEmpty()){
                List<Predict> predictMissions = predictMapper.queryStatusPredictingList(); // 查询状态为 “待识别” 的任务列表
                for (Predict predictMission : predictMissions){
                    predictMission.setStatus("待识别");
                    predictMission.setRunning(false);
                    predictMapper.updatePredict(predictMission);
                }
            }

            if (status == 0 && processMap.isEmpty()) {
                List<Predict> predictMissions = predictMapper.queryStatusWaitList(); // 查询状态为 “待识别” 的任务列表
                if (!predictMissions.isEmpty()) {
                    Predict predictMission = predictMissions.get(0); // 选取第一个未开始的任务
                    int id = predictMission.getId();
                    /*
                    改为调用predict
                     */
                    result=predict(id);
                    return result;

//                    int trainMissionId = predictMission.getTrainMissionId();
//                    String modelName = trainMissionService.selectTrainMissionById(trainMissionId).getModel();
//                    Integer modelUserId = modelService.selectModelById(trainMissionService.selectTrainMissionById(trainMissionId).getModelId()).getUserId();
//                    String datasetTrainLocation = app01DatasetService.selectApp01DatasetById(trainMissionService.selectTrainMissionById(trainMissionId).getDatasetTrainId()).getLocation();
//                    String datasetTrainName = app01DatasetService.selectApp01DatasetById(trainMissionService.selectTrainMissionById(trainMissionId).getDatasetTrainId()).getName();
//                    String datasetValLocation = app01DatasetService.selectApp01DatasetById(trainMissionService.selectTrainMissionById(trainMissionId).getDatasetValId()).getLocation();
//                    String datasetValName = app01DatasetService.selectApp01DatasetById(trainMissionService.selectTrainMissionById(trainMissionId).getDatasetValId()).getName();
//                    int batchSize = trainMissionService.selectTrainMissionById(trainMissionId).getBatchSize();
//                    int minEpoch = trainMissionService.selectTrainMissionById(trainMissionId).getMinEpoch();
//                    int maxEpoch = trainMissionService.selectTrainMissionById(trainMissionId).getMaxEpoch();
//                    Integer earlyStop = trainMissionService.selectTrainMissionById(trainMissionId).getEarlyStop();
//                    Float opLr = trainMissionService.selectTrainMissionById(trainMissionId).getOpLr();
//                    Integer modelId = trainMissionService.selectTrainMissionById(trainMissionId).getModelId();
//                    String location = app01DatasetService.selectApp01DatasetById(predictMission.getDatasetId()).getLocation();
//                    int datasetId = predictMission.getDatasetId();
//
////                    status设置为识别中
//                    predictMission.setStatus("识别中");
//                    predictMission.setBeginTime(new java.util.Date());
//                    predictMission.setRunning(true);
//                    predictMapper.updatePredict(predictMission);

//		System.out.println("modelName: "+modelName);
//		System.out.println("modelUserId: "+modelUserId);
//		System.out.println("datasetTrainLocation: "+datasetTrainLocation);
//		System.out.println("datasetTrainName: "+datasetTrainName);
//		System.out.println("datasetValLocation: "+datasetValLocation);
//		System.out.println("datasetValName: "+datasetValName);
//		System.out.println("batchSize: "+batchSize);
//		System.out.println("minEpoch: "+minEpoch);
//		System.out.println("maxEpoch: "+maxEpoch);
//		System.out.println("earlyStop: "+earlyStop);
//		System.out.println("opLr: "+opLr);
//		System.out.println("modelId: "+modelId);
//		System.out.println("location: "+location);
//		System.out.println("datasetId: "+datasetId);

                    //获取当前路径
//                    String currentPath = System.getProperty("user.dir");
//                    String parentParentPath = Utils.getParentPath(currentPath, 0);
////		parentParentPath: /home/jolly/develop/project/java
//                    currentPath = parentParentPath + "/src/main/resources/CorsicanFire/segmentation";
//                    Process process = null;
//
//                    try {
//                        // 使用 ProcessBuilder 启动进程
//                        ProcessBuilder pb = new ProcessBuilder("python", currentPath + "/predict_java.py", String.valueOf(trainMissionId),
//                                modelName, String.valueOf(modelUserId), datasetTrainLocation,
//                                datasetTrainName, datasetValLocation, datasetValName, String.valueOf(batchSize),
//                                String.valueOf(minEpoch), String.valueOf(maxEpoch), String.valueOf(earlyStop), String.valueOf(opLr),
//                                String.valueOf(modelId), location, String.valueOf(datasetId),
//                                String.valueOf(predictMission.getUserId())
//                        );
//                        pb.redirectErrorStream(true); // 合并标准输出和标准错误
//                        process = pb.start();
//
//                        // 读取 Python 脚本的输出
//                        Process finalProcess = process; // 为了在内部类中使用
//                        new Thread(() -> {
//                            try (BufferedReader reader = new BufferedReader(new InputStreamReader(finalProcess.getInputStream()))) {
//                                String line;
//                                while ((line = reader.readLine()) != null) {
//                                    System.out.println(line);
//                                }
//                            } catch (Exception e) {
//                                e.printStackTrace();
//                            }
//                        }).start();
//                        System.out.println("Python 脚本已启动");
//                        // 保存进程信息
//                        processMap.put(id, process);
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                    }
//                    if (process != null) {
//                        // 等待 Python 脚本执行完毕
//                        try {
//                            int i = process.waitFor();
//                            System.out.println("Python 脚本已执行完毕");
//                            //		运行对比图
//                            System.out.println("返回值："+i);
//                            if (i == 0) {
//                                try {
//                                    // 使用 ProcessBuilder 启动进程
//                                    ProcessBuilder pb = new ProcessBuilder("python", currentPath + "/compare_saveImage.py", location, currentPath
//                                            + "/../../predictResult/" + predictMission.getUserId() +'/'
//                                            +String.valueOf(predictMission.getTrainMissionId()) + "/" + predictMission.getDatasetId() + "/predictResult");
//                                    pb.redirectErrorStream(true); // 合并标准输出和标准错误
//                                    process = pb.start();
//                                    System.out.println("Python 识别对比脚本已启动");
//
//                                    // 读取 Python 脚本的输出
//                                    Process finalProcess = process; // 为了在内部类中使用
//                                    new Thread(() -> {
//                                        try (BufferedReader reader = new BufferedReader(new InputStreamReader(finalProcess.getInputStream()))) {
//                                            String line;
//                                            while ((line = reader.readLine()) != null) {
//                                                System.out.println(line);
//                                            }
//                                        } catch (Exception e) {
//                                            e.printStackTrace();
//                                        }
//                                    }).start();
//                                    processMap.put(id, process);
//                                } catch (IOException e) {
//                                    e.printStackTrace();
//                                }
//
//                                // 等待 Python 脚本执行完毕
//                                try {
//                                    process.waitFor();
//                                    System.out.println("Python 识别结果对比脚本已执行完毕");
                                    /*
                                    到下一个注释前不需要恢复
                                     */


//                                    System.out.println("准备执行tifToGeojson脚本");
//                                    boolean exist = FileUtils.isExist(location + "/tif");
//                                    System.out.println("existence of tif folder: "+exist);
//                                    if (FileUtils.isExist(location + "/tif")){
//                                        System.out.println("predict_java.py 执行完毕" );
//// 创建jsonOutput文件夹
//                                        String jsonOutputPath = currentPath + "/../../predictResult/" + predictMission.getUserId() + '/'
//                                                + (predictMission.getTrainMissionId()) + "/" + predictMission.getDatasetId() + "/jsonOutput/";
//                                        FileUtils.createFolder(jsonOutputPath);
//                                        ProcessBuilder pb = new ProcessBuilder(
//                                                "python",
//                                                currentPath + "/tifToGeojson.py",  // 脚本路径
//                                                "--image_folder", location + "/tif/",  // 图像文件夹路径
//                                                "--label_folder", currentPath + "/../../predictResult/" + predictMission.getUserId() + '/'
//                                                + (predictMission.getTrainMissionId()) + "/" + predictMission.getDatasetId() + "/predictResult/",  // 标签文件夹路径
//                                                "--output_folder", currentPath + "/../../predictResult/" + predictMission.getUserId() + '/'
//                                                + (predictMission.getTrainMissionId()) + "/" + predictMission.getDatasetId() + "/jsonOutput/"  // 输出文件夹路径
//                                        );
//                                        System.out.println("执行tifToGeojson脚本命令: " + pb.command());
//                                        pb.redirectErrorStream(true); // 合并标准输出和标准错误
//
//                                        // 启动tifToGeojson脚本
//                                        new Thread(() -> {
//                                            try {
//                                                Process tifProcess = pb.start();
//                                                System.out.println("Python tifToGeojson脚本已启动");
//
//                                                // 读取 Python 脚本的输出
//                                                try (BufferedReader reader = new BufferedReader(new InputStreamReader(tifProcess.getInputStream()))) {
//                                                    String line;
//                                                    while ((line = reader.readLine()) != null) {
//                                                        System.out.println(line);  // 打印输出
//                                                    }
//                                                }
//                                                tifProcess.waitFor();
//                                            } catch (IOException | InterruptedException e) {
//                                                e.printStackTrace();
//                                            }
//                                        }).start();
//                                    }
                                    /*
                                    走以下开始恢复注释
                                     */
//                                    PredictController tmp=new PredictController();
////                                    System.out.println("progress:------------------"+tmp.getProgress(predictMission.getId()).get("status").toString());
////                                    if (tmp.getProgress(predictMission.getId()).get("status").toString().equals("100.0") ){
//                                        predictMission.setStatus("已完成");
//                                        predictMission.setRunning(false);
//                                        predictMission.setEndTime(new java.util.Date());
//                                        predictMapper.updatePredict(predictMission);
////                                    }
//                                } catch (InterruptedException e) {
//                                    e.printStackTrace();
//                                }
//                            }
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        } finally {
//                            processMap.remove(id);
//                            if (!stopFlag) {
//                                doPredict();
//                            } else {
//                                System.out.println("全局停止标志已设置，停止识别任务");
//                            }
//                        }
//                    } else {
//                        System.out.println("Python 脚本启动失败");
//                        predictMission.setStatus("识别异常");
//                        predictMapper.updatePredict(predictMission);
//                        predictMission.setRunning(false);
//                        return 1;
//                    }
                }
            }
        }catch (Exception e) {
            e.printStackTrace();
        } finally {
//            lock.unlock();
        }
        return 0;
    }


    @Override
    public int stopPredict() {
        lock.lock(); // 加锁，确保在停止期间没有其他任务启动
        try {
            stopFlag = true; // 设置停止标志
            boolean allTerminated = true;

            // 遍历 processMap 中的所有进程，终止每个进程
            for (Map.Entry<Integer, Process> entry : processMap.entrySet()) {
                Process process = entry.getValue();
                int predictMissionId = entry.getKey();

                if (process.isAlive()) {
                    process.destroy(); // 终止进程
                    try {
                        process.waitFor(); // 等待进程完全结束
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        allTerminated = false; // 如果等待进程时发生异常，标记为未完全终止
                    }

                    // 更新训练任务状态为停止
                    Predict predictMission = predictMapper.selectPredictById(predictMissionId);
                    if (predictMission != null) {
                        predictMission.setStatus("未识别"); // 将任务状态设置为未开始
                        predictMission.setRunning(false); // 设置为停止
                        predictMapper.updatePredict(predictMission);
                    }
                }
            }

            // 清空 processMap
            processMap.clear();

            return allTerminated ? 0 : 1; // 返回 0 表示成功终止所有进程，1 表示部分进程未成功终止
        } finally {
            stopFlag = false; // 操作完成后，允许以后再次启动任务
            lock.unlock(); // 释放锁
            doPredict();
        }
    }

    @Override
    public int updateStatusToWait(int id) {
        Predict predictMission = predictMapper.selectPredictById(id);
        if (predictMission != null) {
            predictMission.setStatus("待识别"); // 将任务状态设置为待训练
            predictMission.setRunning(false); // 设置为停止
            predictMapper.updatePredict(predictMission);
            return 1;
        } else {
            return 0;
        }
    }

    @Override
    public int updateStatusToNotPredict(int id) {
        Predict predictMission = predictMapper.selectPredictById(id);
        if (predictMission != null) {
            predictMission.setStatus("未识别"); // 将任务状态设置为未开始
            predictMission.setRunning(false); // 设置为停止
            predictMapper.updatePredict(predictMission);
            predictMapper.setTimeToQueueNull(id);
            return 1;
        } else {
            return 0;
        }
    }

    @Override
    public void setTimeToQueue(int id) {
        predictMapper.setTimeToQueue(id);
    }

    @Override
    public void setTimeToQueueNull(int id) {
        predictMapper.setTimeToQueueNull(id);
    }

    @Override
    public boolean isPredictNameExists(String name, int userId) {
        Integer count = predictMapper.isPredictNameExists(name, userId);
        return count != null && count > 0;
    }

    @Override
    public List<Predict> selectWaitAndPredictingList(Object o) {
        return predictMapper.selectWaitAndPredictingList();
    }

    @Override
    public int calculateQueuePosition(Date timeToQueue, Integer id) {
        // 查询所有任务并根据 timeToQueue 排序，找到当前任务的队列位次
        List<Predict> missions = predictMapper.selectAllPredictMissionsOrderedByTime();
//        System.out.println(missions);
        int position = 1;

        for (Predict mission : missions) {
            if (mission.getId() == id.intValue()) {
//                System.out.println("position: "+position);
                break;
            }
            position++;
        }

        return position;
    }

    @Override
    public boolean isPredictMissionUnique(int trainMissionId, int datasetId, int userId) {
        Integer count = predictMapper.isPredictMissionUnique(trainMissionId, datasetId,userId);
        return count != null && count > 0;
    }

    @Override
    public List<Predict> selectPredictListWithSameUserId(int currentUserId, Predict predict) {
        List<Predict> predicts = predictMapper.selectPredictListWithSameUserId(currentUserId, predict);
        return predicts;
    }


}
